package com.lin.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lin.exception.KaptchaNotMatchException;
import com.lin.utils.JWTUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 时间：2023/8/20
 */
public class MyLoginFilter extends UsernamePasswordAuthenticationFilter {
    
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    public static final String FORM_KAPTCHA_KEY = "kaptcha";

    private String kaptchaParameter = FORM_KAPTCHA_KEY;

    public String getKaptchaParameter() {
        return kaptchaParameter;
    }

    public void setKaptchaParameter(String kaptchaParameter) {
        this.kaptchaParameter = kaptchaParameter;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            //获取请求数据
            Map<String,String> map = objectMapper.readValue(request.getInputStream(), Map.class);
            //获取 session 中验证码
//            String sessionVerifyCode = (String) request.getSession().getAttribute("kaptcha");
            //获取redis中验证码
            String sessionVerifyCode = stringRedisTemplate.opsForValue().get("kaptcha");
            //获取请求中验证码
            String kaptcha = map.get(getKaptchaParameter());
            //获取用户名和密码
            String username = map.get(getUsernameParameter());
            String password = map.get(getPasswordParameter());
            //校验验证码成功--进行身份校验
            if(!ObjectUtils.isEmpty(kaptcha) && !ObjectUtils.isEmpty(sessionVerifyCode) &&
                    kaptcha.equalsIgnoreCase(sessionVerifyCode)){
                //判断用户名密码是否正确
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, password);
                setDetails(request,usernamePasswordAuthenticationToken);
                Authentication authenticate = this.getAuthenticationManager().authenticate(usernamePasswordAuthenticationToken);
                if(authenticate!=null){
                    //认证成功，自动将用户信息保存到securityContextHolder中
                    Map<String,Object> tokenInfo = new HashMap<>();
                    tokenInfo.put("username",username);
                    //返回token
                    String token = JWTUtil.jwt(tokenInfo);
                    System.out.println(token);
                }
                return authenticate;
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        throw new KaptchaNotMatchException("验证码错误");
    }
}
